home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / dsp / 56200tar.z / 56200tar / 56200 / p3 < prev    next >
Text File  |  1992-04-28  |  26KB  |  519 lines

  1.  
  2.          /***********************************************\
  3.          |**                                           **|
  4.          |**   DSP56200 CHIP DRIVER -ADAPTIVE FILTER   **|
  5.          |**                        -INTERRUPT DRIVEN  **|
  6.          |**                                           **|
  7.          \***********************************************/
  8.  
  9.  
  10.  
  11. /************************************************************************\
  12. *                                                                        *
  13. *   This is an example of a program located in a host processor, used    *
  14. *   to setup and service the DSP56200 as a real-time adaptive filter.    *
  15. *   In this example, the host processor is interrupted at the beginning  *
  16. *   of every new sample period, signified by the reception of a rising   *
  17. *   edge on the DSP56200's START pin.  The host processor's interrupt    *
  18. *   pin is tied to the START pin of the DSP56200 through an inverter.    *
  19. *                                                                        *
  20. *   This program, written in the language "C", is provided only as an    *
  21. *   example, and will be much faster if translated by the user into the  *
  22. *   assembly language of the host processor.                             *
  23. *                                                                        *
  24. *                                                                        *
  25. *   The example system is configured as shown below:                     *
  26. *                                                                        *
  27. *                                                                        *
  28. *                               ------------                             *
  29. *                               | DSP56200 |                             *
  30. *                               ------------                             *
  31. *                                     ^                                  *
  32. *                                     |                                  *
  33. *                                     v                                  *
  34. *                  -------    ------------------                         *
  35. *          d(t) -->| A/D |--->| Host Processor |                         *
  36. *                  -------    |                |    -------              *
  37. *                             | (contains code |--->| D/A |--> out(t)    *
  38. *                  -------    |  found in this |    -------              *
  39. *         x1(t) -->| A/D |--->|     file)      |                         *
  40. *                  -------    ------------------                         *
  41. *                                                                        *
  42. *                                                                        *
  43. *                    Figure 1. Adaptive Filtering System                 *
  44. *                                                                        *
  45. *                                                                        *
  46. *                                                                        *
  47. *   There is only one DSP56200 in this example (i.e., not multiple       *
  48. *   DSP56200s in cascade), and it is configured as an adaptive filter    *
  49. *   (see Figure 2) by writing the DSP56200's Configuration register.     *
  50. *   Since only 16 bits of the result  are sent to the D/A Converter,     *
  51. *   the output is rounded to a 16 bit result by the DSP56200.            * 
  52. *                                                                        *
  53. *                                                                        *
  54. *                                                                        *
  55. *                                                                        *
  56. *         d(n) -------------------------------                           *
  57. *                                          - |                           *
  58. *                                            v                           *
  59. *                    --------------     +   ---                          *
  60. *        x1(n) ----->|    FIR     |------->| + |-----> out(n)            *
  61. *                    |  Structure |         ---           = -1 * error   *
  62. *                    --------------          |                           *
  63. *                          ^                 |                           *
  64. *                          |                 |                           *
  65. *                          -------------------                           *
  66. *                                                                        *
  67. *                                                                        *
  68. *                   Figure 2. DSP56200 Configuration                     *
  69. *                                                                        *
  70. *                                                                        *
  71. *                                                                        *
  72. *      ************************************************************      *
  73. *      *                                                          *      *
  74. *      *   This program originally available on the Motorola DSP  *      *
  75. *      *   bulletin board.  It is provided under a DISCLAMER OF   *      *
  76. *      *   WARRANTY available from  Motorola DSP Operation,       *      *
  77. *      *     6501 Wm. Cannon Drive W., Austin, Tx., 78735.        *      *
  78. *      *                                                          *      *
  79. *      ************************************************************      *
  80. *                                                                        *
  81. *                                                                        *
  82. *                                                                        *
  83. *      ************************************************************      *
  84. *      * Note on the Representation of Hex Numbers:               *      *
  85. *      *                                                          *      *
  86. *      *    In the programming language  "C",  hex numbers are    *      *
  87. *      *    represented by preceding the number with "0x". For    *      *
  88. *      *    example, e4 (hex) is represented in "C" as 0xe4.      *      *
  89. *      *                                                          *      *
  90. *      ************************************************************      *
  91. *                                                                        *
  92. \************************************************************************/
  93.  
  94.  
  95.  
  96.         /*** CONSTANTS ***/
  97.  
  98. #define   PASS_CONFIG   3       /* Pass for Configuring the DSP56200 */
  99. #define   PASS_RAMINIT  2       /* Pass for Initializing the RAMs    */
  100. #define   PASS_ENABLE   1       /* Pass for Enabling Coeff Updates   */
  101. #define   PASS_REALTIM  0       /* Pass for Realtime Filtering       */
  102.  
  103.  
  104.  
  105. #define   X1_HI     0x0         /* Addresses (hex) of DSP56200 regs, bank 0 */
  106. #define   X1_LO     0x1
  107. #define   D_HI      0x2
  108. #define   D_LO      0x3
  109. #define   K_HI      0x4
  110. #define   K_LO      0x5
  111. #define   X2_HI     0x6                     /* unused -Dual FIR mode only */
  112. #define   X2_LO     0x7                     /* unused -Dual FIR mode only */
  113. #define   DATA_HI   0x8                     /* unused */
  114. #define   DATA_LO   0x9                     /* unused */
  115. #define   COEFF_HI  0xa
  116. #define   COEFF_MD  0xb
  117. #define   COEFF_LO  0xc
  118. #define   RAM_ADR   0xd
  119. #define   CONFIG    0xf
  120.  
  121. #define   OUTPUT3   0x0               /* Most  significant byte of result */
  122. #define   OUTPUT2   0x1
  123. #define   OUTPUT1   0x2               /* Two least significant bytes are  */
  124. #define   OUTPUT0   0x3               /* unused since rounded to 16 bits */
  125. #define   LTAP1_HI  0x4                     /* unused */
  126. #define   LTAP1_LO  0x5                     /* unused */
  127. #define   LTAP2_HI  0x6                     /* unused */
  128. #define   LTAP2_LO  0x7                     /* unused */
  129.  
  130. #define   LEAKAGE   0x0         /* Addresses (hex) of DSP56200 regs, bank 1 */
  131. #define   FTL       0x1
  132.  
  133.  
  134.  
  135. #define   LKG_VAL   0x00        /* Values (hex) written to the DSP56200 regs */
  136. #define   FTL_VAL   0xff              /* 256 taps */
  137. #define   DCONFIG_0 0x98              /* Updates disabled, Selects bank 0   */
  138. #define   DCONFIG_1 0x99              /* Updates disabled, Selects bank 1   */
  139. #define   ECONFIG_0 0x90              /* Updates enabled,  Selects bank 0   */
  140. #define   KVAL_HI   0x04
  141. #define   KVAL_LO   0x00              /* It may be desirable to make the K 
  142.                                          register a variable so it can be 
  143.                                          updated every sample period.   */
  144.  
  145.  
  146.         /*** GLOBAL VARS ***/
  147.  
  148. int  tap;                             /* filter tap number */
  149. int  passnum;                         /* Determines action taken by the
  150.                                          interrupt service routine when
  151.                                          a START interrupt is received.  */
  152.  
  153.  
  154.  
  155.         /*** MAIN PROGRAM ***/
  156.  
  157. main()   {
  158.  
  159.         /********************************************************************\
  160.         *                                                                    *
  161.         *   This program is an example of the software used by a host        *
  162.         *   processor to service a DSP56200 configured as an adaptive        *
  163.         *   filter.  Three functions are performed:                          *
  164.         *                                                                    *
  165.         *         1. Initialize User's System and Configure the DSP56200.    *
  166.         *         2. Zero the Coeff and Data RAMs of the DSP56200.           *
  167.         *         3. Run the Adaptive Filter in a real-time environment.     *
  168.         *                                                                    *
  169.         *   Things to watch for when setting up an adaptive filter system:   *
  170.         *                                                                    *
  171.         *         - There must be NO GLITCHES on the DSP56200's START pin.   *
  172.         *         - The SEI pin must be directly wired to the SSO pin.       *
  173.         *         - The value of the K register must not be too large.       *
  174.         *         - If codecs are used for the A/D or D/A conversion, see    *
  175.         *              comments in the routines "send_da()"and "get_ad()".   *
  176.         *         - If offset binary A/Ds or D/As are used, see comments     *
  177.         *              in the subroutines "send_da()" and "get_ad()".        *
  178.         *                                                                    *
  179.         *   Note: The program assumes that the variable type "int" is at     *
  180.         *         least 16 bits wide.                                        *
  181.         *                                                                    *
  182.         \********************************************************************/
  183.  
  184.  
  185.  
  186.         /* Program Setup */
  187.  
  188.            /* The host must disable the START Interrupt */
  189.  
  190.            /* Then, global vars are set up for the routine "irealtime()" */
  191.               passnum = PASS_CONFIG;
  192.               tap = 0;
  193.  
  194.  
  195.  
  196.         /* Initialize System */
  197.  
  198.            /*  Here the user first initializes any other components of the  */
  199.            /*  adaptive filtering system which require initialization. The  */
  200.            /*  DSP56200 is then initialized using the program code below.   */
  201.  
  202.  
  203.  
  204.         /* The host must now enable the START Interrupt */
  205.  
  206.  
  207.  
  208.         /* Run the Adaptive Filter in Real-time */
  209.  
  210.            /*  At this point the program can either start executing some     */
  211.            /*  other task or it can idle.  Upon reception of a START signal  */
  212.            /*  (i.e. when interrupted), the host calls the interrupt service */
  213.            /*  routine "irealtime()".  Upon completion of "irealtime()",     */
  214.            /*  the host either continues its other processing or idles.      */
  215. }
  216.  
  217.  
  218.  
  219.         /*** SUBROUTINES ***/
  220.  
  221.  
  222.  
  223.         /* IREALTIME */
  224.  
  225. irealtime()
  226. {
  227.         /****************************************************************\
  228.         *                                                                *
  229.         *   This interrupt service routine will perform one of the       *
  230.         *   following four tasks when executed:                          *
  231.         *                                                                *
  232.         *         Task 1. Configure the DSP56200.                        *
  233.         *                                                                *
  234.         *         Task 2. Clear one location in the Data RAM and         *
  235.         *                 one location in the Coefficient RAM.           *
  236.         *                                                                *
  237.         *         Task 3. Enable Updates of the Coefficients.            *
  238.         *                                                                *
  239.         *         Task 4. Send two new data samples to the DSP56200      *
  240.         *                 and read out one error term from the chip.     *
  241.         *                                                                *
  242.         *   When the user's system comes out of reset, the DSP56200 is   *  
  243.         *   first configured (Task 1).  Then, the host processor will    *
  244.         *   execute Task 2 when interrupted so that the DSP56200 RAMs    *
  245.         *   get initialized.  Upon receiving each new interrupt, Task 2  *
  246.         *   is executed until the RAM initialization is completed. The   *
  247.         *   host processor then uses one sample period (i.e. the next    *
  248.         *   interrupt) to enable updates of the coefficients.  From this *
  249.         *   time on, the host executes Task 4 with each new interrupt it *
  250.         *   receives.  If the user wants to update the value of the K    *
  251.         *   (loop gain) register, it could also be done within Task 4.   *
  252.         *                                                                *
  253.         *   This routine is used only in interrupt driven systems.       *
  254.         *   Since this is an interrupt service routine, it may be        *
  255.         *   necessary to save the status of the host processor upon      *
  256.         *   entering this routine, and to restore the processor's        *
  257.         *   status upon exiting this routine.  It may also be important  *
  258.         *   to disable any interrupts of lower priority when entering    *
  259.         *   this routine, and to reenable these interrupts upon exiting. *
  260.         *                                                                *
  261.         *   Note: The routine assumes that the variable type "int" is    *
  262.         *         at least 16 bits wide.                                 *
  263.         *                                                                *
  264.         *   Also: The DSP56200 outputs "-1 * error".  If the correct     *
  265.         *         sign for the error term is required, then the host     *
  266.         *         processor must perform a 2's complement operation      *
  267.         *         on the 16 bit value read from the DSP56200's OUTPUT    *
  268.         *         register (bytes 3 and 2).                              *
  269.         *                                                                *
  270.         *   Also: It is important that execution of this routine         *
  271.         *         completes before the next START interrupt arrives,     *
  272.         *         i.e., it must complete in one sample period.   If      *
  273.         *         Task 1 will not complete in one sample period, it      *
  274.         *         can be broken into two shorter tasks,  requiring       *
  275.         *         two sample periods.                                    *
  276.         *                                                                *
  277.         \****************************************************************/
  278.  
  279.  
  280.  
  281.         /* Subroutine Declarations */
  282.            int x1, d, out;                                 /* see Figure 2 */
  283.  
  284.  
  285.  
  286.         /* Select Correct Task to Execute */
  287.  
  288.         /* TASK 1 */
  289.  
  290.            if (passnum == PASS_CONFIG)   {
  291.  
  292.               /* Reset and Configure the DSP56200 */
  293.  
  294.                  wrbyte(DCONFIG_1, CONFIG); /* Configuration:                */
  295.                                             /*    - Single Adaptive Filter   */
  296.                                             /*    - Not Cascaded             */
  297.                                             /*    - 16 Bit Rounding          */
  298.                                             /*    - Coeff Update Disabled    */
  299.                                             /*    - DC Tap Disabled          */
  300.                                             /*    - Leakage Disabled         */
  301.                                             /*    - Register Bank 1 Selected */
  302.                  wrbyte(FTL_VAL, FTL);      /* Writing this reg also resets  */
  303.                                             /*   the chip at the beginning   */
  304.                                             /*   of the next sample period,  */
  305.                                             /*   which destroys any previous */
  306.                                             /*   contents of the Data RAM.   */
  307.                  wrbyte(LKG_VAL, LEAKAGE);
  308.  
  309.                  wrbyte(DCONFIG_0, CONFIG); /* Switch to register bank 0 */
  310.  
  311.                  wrbyte(KVAL_HI, K_HI);
  312.                  wrbyte(KVAL_LO, K_LO);
  313.  
  314.               /* Setup the DSP56200 registers for RAM initialization */
  315.  
  316.                     wrbyte(0, X1_HI); /* clears Data RAM when loading coeffs */
  317.                     wrbyte(0, X1_LO);
  318.  
  319.                     wrbyte(0, D_HI);
  320.                     wrbyte(0, D_LO);
  321.  
  322.                     wrbyte(0, COEFF_HI);      /* Coeff_RAM[0] = 0 */
  323.                     wrbyte(0, COEFF_MD);
  324.                     wrbyte(0, COEFF_LO);
  325.  
  326.                     wrbyte(0, RAM_ADR);   /* autoincrements w/ each START */
  327.  
  328.                     passnum = passnum-1;  /* Goes to PASS_RAMINIT on      */
  329.                                           /* next START interrupt         */
  330.               /* Exit Routine */
  331.                  return;
  332.            }
  333.  
  334.         /* TASK 2 */
  335.  
  336.            if (passnum == PASS_RAMINIT)   {
  337.  
  338.              /* Clear 1 Location in the DSP56200's Coefficient and Data RAMS */
  339.  
  340.                  tap = tap + 1;
  341.  
  342.                  wrbyte(0, COEFF_HI);      /* Coeff_RAM[tap] = 0 */
  343.                  wrbyte(0, COEFF_MD);
  344.                  wrbyte(0, COEFF_LO);
  345.                                        /*  Note that the Data RAM is also   */
  346.                                        /*  cleared since the DSP56200's X1  */
  347.                                        /*  reg is set to "0", resulting in  */
  348.                                        /*  "0"s being "shifted" into the    */
  349.                                        /*  filter's Data RAM (delay line)   */
  350.                                        /*  every sample period.             */
  351.  
  352.                  if (tap == FTL_VAL)
  353.                     passnum = passnum-1;            /* Goes to PASS_ENABLE on
  354.                                                        next START interrupt */
  355.  
  356.               /* Exit Routine */
  357.                  return;
  358.            }
  359.  
  360.         /* TASK 3 */
  361.  
  362.            if (passnum == PASS_ENABLE)   {         
  363.  
  364.                  wrbyte(ECONFIG_0, CONFIG);         /* Enables coeff updates by
  365.                                                        toggling bit 3 to "0" */
  366.  
  367.                  passnum = passnum-1;               /* Goes to PASS_REALTIM on
  368.                                                        next START interrupt */
  369.  
  370.                  return;                            /* Exit Routine */
  371.            }
  372.  
  373.         /* TASK 4 */
  374.  
  375.            if (passnum == PASS_REALTIM)   {
  376.  
  377.              /* Read the New Samples from the A/Ds and Write to the DSP56200 */
  378.  
  379.                  x1 = get_ad(1);
  380.                  d  = get_ad(2);
  381.  
  382.                  wrbyte((x1>>8) & 0x0ff, X1_HI);      /* writes upper byte */
  383.                  wrbyte( x1     & 0x0ff, X1_LO);      /* writes lower byte */
  384.                  wrbyte((d>>8)  & 0x0ff, D_HI);       /* writes upper byte */
  385.                  wrbyte( d      & 0x0ff, D_LO);       /* writes lower byte */
  386.  
  387.               /* Read Error Term from the 56200 and Write to the D/A */
  388.  
  389.                  out = rdbyte(OUTPUT3);
  390.                  out = out << 8;                      /* move to upper byte */
  391.                  out = out + (0x0ff & rdbyte(OUTPUT2));
  392.  
  393.                  send_da(out);
  394.  
  395.               /* Exit Routine */
  396.                  return;
  397.            }
  398. }
  399.  
  400.  
  401.  
  402.         /* WRBYTE */
  403.  
  404. wrbyte(val,adr)
  405. int val, adr;
  406. {
  407.         /**************************************************************\
  408.         *                                                              *
  409.         *   This subroutine writes one byte to the DSP56200 register   *
  410.         *   specified by "adr".                                        *
  411.         *   Note that the correct register bank has already been       *
  412.         *   selected (defined by the LSB of the Configuration reg).    *
  413.         *                                                              *
  414.         *   This subroutine could be defined as a macro for faster     *
  415.         *   execution.                                                 *
  416.         *                                                              *
  417.         *   Inputs:                                                    *
  418.         *      val  = bytewide value to be written to the DSP56200     *
  419.         *      adr  = address of the DSP56200 register to be written   *
  420.         *                                                              *
  421.         \**************************************************************/
  422.  
  423.         /* Actual program code depends on the user's system. */
  424. }
  425.  
  426.  
  427.  
  428.         /* RDBYTE */
  429.  
  430. rdbyte(adr)
  431. int adr;
  432. {
  433.         /**************************************************************\
  434.         *                                                              *
  435.         *  This subroutine reads one byte from the DSP56200 register   *
  436.         *  specified by "adr".                                         *
  437.         *  Note that the correct register bank has already been        *
  438.         *  selected (defined by the LSB of the Configuration reg).     *
  439.         *                                                              *
  440.         *  This subroutine could be defined as a macro for faster      *
  441.         *  execution.                                                  *
  442.         *                                                              *
  443.         *   Inputs:                                                    *
  444.         *      adr  = address of the DSP56200 register to be read      *
  445.         *                                                              *
  446.         *   Outputs:                                                   *
  447.         *      The routine returns the byte read from the DSP56200     *
  448.         *                                                              *
  449.         \**************************************************************/
  450.  
  451.         int valread;
  452.  
  453.         /* Actual program code depends on the user's system. */
  454.  
  455.         return(valread);
  456. }
  457.  
  458.  
  459.  
  460.         /* GET_AD */
  461.  
  462. get_ad(devnum)
  463. int devnum;
  464. {
  465.         /******************************************************************\
  466.         *                                                                  *
  467.         *   This subroutine returns a 16 bit value read from one of the    *
  468.         *   two A/D converters in the filtering system.                    *
  469.         *                                                                  *
  470.         *   Inputs:                                                        *
  471.         *      devnum = A/D Converter number:  1 = x1 input, 2 = d input.  *
  472.         *                                                                  *
  473.         *   Outputs:                                                       *
  474.         *      The routine returns the value read from the selected A/D.   *
  475.         *                                                                  *
  476.         \******************************************************************/
  477.  
  478.         int ad_val;
  479.  
  480.         /* Actual program code depends on the user's system. */
  481.  
  482.         /*  If a codec is used for A/D conversion, the 8 bit companded  */
  483.         /*  sample must be converted into a 12 bit linear quantity and  */
  484.         /*  then sign extended to 16 bits.                              */
  485.  
  486.         /*  If the converter uses an offset binary format, it may be  */
  487.         /*  necessary to invert the sign bit (and any sign extension  */
  488.         /*  bits) to obtain a 2's complement number.                  */
  489.  
  490.         return(ad_val);
  491. }
  492.  
  493.  
  494.  
  495.         /* SEND_DA */
  496.  
  497. send_da(val)
  498. int val;
  499. {
  500.         /**************************************************************\
  501.         *                                                              *
  502.         *   This subroutine sends a value to a D/A converter where it  *
  503.         *   gets converted to an analog signal.                        *
  504.         *                                                              *
  505.         *   Inputs:                                                    *
  506.         *      val = value to be sent to the D/A converter             *
  507.         *                                                              *
  508.         \**************************************************************/
  509.  
  510.         /* Actual program code depends on the user's system. */
  511.  
  512.         /*  If a codec is used for D/A conversion, the 16 bit linear   */
  513.         /*  sample must be converted into a 8 bit companded quantity.  */
  514.  
  515.         /*  If the converter uses an offset binary format, it may be  */
  516.         /*  necessary to invert the sign bit (and any sign extension  */
  517.         /*  bits) to obtain a number in offset binary format.         */
  518. }
  519.